﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Win32;

namespace Utilities
{
    public class ClsRegistry
    {
        private readonly RegistryKey _baseRegistryKey = Registry.CurrentUser;
        private readonly string _subKey = "SOFTWARE\\" + Application.ProductName;
        private const bool ShowError = false;

        public string Read(string keyName)
        {
            // Opening the registry key
            var rk = _baseRegistryKey;
            // Open a subKey as read-only
            var sk1 = rk.OpenSubKey(_subKey);
            // If the RegistrySubKey doesn't exist -> (null)
            if (sk1 == null)
            {
                return null;
            }
            else
            {
                try
                {
                    // If the RegistryKey exists I get its value
                    // or null is returned.
                    return (string)sk1.GetValue(keyName.ToUpper());
                }
                catch (Exception e)
                {
                    // AAAAAAAAAAARGH, an error!
                    ShowErrorMessage(e, "Reading registry " + keyName.ToUpper());
                    return null;
                }
            }
        }

        public bool Write(string keyName, object value)
        {
            try
            {
                // Setting
                var rk = _baseRegistryKey;
                // I have to use CreateSubKey 
                // (create or open it if already exits), 
                // 'cause OpenSubKey open a subKey as read-only
                var sk1 = rk.CreateSubKey(_subKey);
                // Save the value
                sk1.SetValue(keyName.ToUpper(), value);

                return true;
            }
            catch (Exception e)
            {
                // AAAAAAAAAAARGH, an error!
                ShowErrorMessage(e, "Writing registry " + keyName.ToUpper());
                return false;
            }
        }

        public bool DeleteKey(string keyName)
        {
            try
            {
                // Setting
                var rk = _baseRegistryKey;
                var sk1 = rk.CreateSubKey(_subKey);
                // If the RegistrySubKey doesn't exists -> (true)
                if (sk1 == null)
                    return true;
                else
                    sk1.DeleteValue(keyName);

                return true;
            }
            catch (Exception e)
            {
                // AAAAAAAAAAARGH, an error!
                ShowErrorMessage(e, "Deleting SubKey " + _subKey);
                return false;
            }
        }

        public bool DeleteSubKeyTree()
        {
            try
            {
                // Setting
                var rk = _baseRegistryKey;
                var sk1 = rk.OpenSubKey(_subKey);
                // If the RegistryKey exists, I delete it
                if (sk1 != null)
                    rk.DeleteSubKeyTree(_subKey);

                return true;
            }
            catch (Exception e)
            {
                // AAAAAAAAAAARGH, an error!
                ShowErrorMessage(e, "Deleting SubKey " + _subKey);
                return false;
            }
        }

        public int SubKeyCount()
        {
            try
            {
                // Setting
                var rk = _baseRegistryKey;
                var sk1 = rk.OpenSubKey(_subKey);
                // If the RegistryKey exists...
                if (sk1 != null)
                    return sk1.SubKeyCount;
                else
                    return 0;
            }
            catch (Exception e)
            {
                // AAAAAAAAAAARGH, an error!
                ShowErrorMessage(e, "Retriving subkeys of " + _subKey);
                return 0;
            }
        }

        public int ValueCount()
        {
            try
            {
                // Setting
                var rk = _baseRegistryKey;
                var sk1 = rk.OpenSubKey(_subKey);
                // If the RegistryKey exists...
                if (sk1 != null)
                    return sk1.ValueCount;
                else
                    return 0;
            }
            catch (Exception e)
            {
                // AAAAAAAAAAARGH, an error!
                ShowErrorMessage(e, "Retriving keys of " + _subKey);
                return 0;
            }
        }

        private void ShowErrorMessage(Exception e, string title)
        {
            if (ShowError)
                MessageBox.Show(e.Message,
                        title
                        , MessageBoxButtons.OK
                        , MessageBoxIcon.Error);
        }

        public ManagementObjectCollection MachineKey(string key)
        {
            var searcher = new ManagementObjectSearcher(string.Format(@"select * from {0}", key));
            var lstResults = searcher.Get();
            foreach (var item in lstResults)
            {
                Console.WriteLine("Item --> " + item);
                foreach (var prop in item.Properties)
                {
                    Console.WriteLine("Name-> {0} Value -> {1}", prop.Name, prop.Value);
                }
            }
            return lstResults;
        }

    }
}
